package club.kynb.mall.application.service;

import club.kynb.mall.application.convert.MallCommonConvertor;
import club.kynb.mall.application.model.model.event.OrderPayNotifyEvent;
import club.kynb.mall.payment.api.ITradeOrderService;
import club.kynb.mall.payment.constant.PayOrderTypeEnum;
import club.kynb.mall.payment.constant.TradeOrderStatusEnum;
import club.kynb.mall.payment.dto.PayTradeOrderDTO;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pizza.event.publish.EventBus;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Optional;

/**
 * 通知处理服务
 * @author kynb_club@163.com
 * @date: 2021/7/11
 */
@Slf4j
@Service
@AllArgsConstructor
public class NotifyApplicationService {

    private final ITradeOrderService tradeOrderService;
    private final EventBus eventBus;
    private final static int FAILURE_CODE = 0;

    public String payNotify(JSONObject request) {
        log.info("订单支付通知 notify:{} 处理开始->>>  ",JSONUtil.toJsonStr(request));
        String success = "success";
        String failure = "failure";
        if(FAILURE_CODE == request.getInt("status")){
            return failure;
        }
        Optional<PayTradeOrderDTO> tradeOrderOptional = tradeOrderService.getByTradeNo(request.getStr("orderNo"));
        //交易流水获取失败
        if(!tradeOrderOptional.isPresent()){
            log.error("未知的订单交易号 ：{}",request.getStr("orderNo"));
            return failure;
        }
        PayTradeOrderDTO tradeOrderDTO = tradeOrderOptional.get();
        //TODO 解析通知信息 这里默认成功
        TradeOrderStatusEnum statusEnum = TradeOrderStatusEnum.SUCCESS;
        // 更新支付流水
        if(!tradeOrderDTO.getStatus().equals(statusEnum.getStatus())){
            tradeOrderDTO.setStatus(statusEnum.getStatus())
                    .setPayAmount(StrUtil.isNotBlank(request.getStr("amount")) ? new BigDecimal(request.getStr("amount")) : null)
                    .setPayFlowNo(StrUtil.emptyToNull(request.getStr("flowNo")))
                    .setNotifyInfo(JSONUtil.toJsonStr(request))
                    .setUpdateTime(new Date())
                    .setPayTime(tradeOrderDTO.getPayTime() == null ? new Date() : null);
            tradeOrderService.update(tradeOrderDTO);
        }
        PayOrderTypeEnum orderTypeEnum = PayOrderTypeEnum.get(tradeOrderDTO.getOriginOrderType()).orElse(null);
        if(orderTypeEnum == null){
            log.error("未知的的支付订单类型: 支付订单号:{}，订单类型：{}",tradeOrderDTO.getTradeOrderNo(),tradeOrderDTO.getOriginOrderType());
            return failure;
        }
        //通知订单
        eventBus.publishEvent(OrderPayNotifyEvent.builder()
                .innerOrderNo(tradeOrderDTO.getOriginOrderNo())
                .orderTypeEnum(orderTypeEnum)
                .statusEnum(MallCommonConvertor.convertPayStatusFromTradeStatus(statusEnum))
                .payAmount(tradeOrderDTO.getPayAmount())
                .payTime(tradeOrderDTO.getPayTime())
                .build()
        );
        log.info("订单支付通知处理结束->>> ");
        return success;
    }
}
